Tutorial de Web Scrapping con Seleniun

Extracción de perfil de RAM de Sitio Web de VigiAccess

1. Introducción

El tutorial mostrado a continuación pretende mostrar algunos de los pasos para realizar Web Scrapping, aunque también se muestran algunos pasos para manipulación (Pandas) y visualización de los datos (Plotly), el enfoque es la extracción de la información de la web.

¿Qué es el Web Scrapping ?

El web scrapping es un método para conversión de datos en formatos legibles por humanos -- contenidos en sitios web -- a formatos legibles por máquinas. La ejecución de web scrapping requiere conocimientos en los fundamentos de tecnologías web tales como HTML, CSS, y JavaScript. Para realizar web scrapping se debe tener en cuenta sí el sitio web es estático o dinámico, en el primer caso el sitio web es fijo y siempre muestra el mismo contenido para cada usuario, en el segundo caso la página muestra un contenido diferente de acuerdo a la interacción realizada por el usuario.

El lenguaje de programación Python tiene varias librerías para web scrapping como BeautifulSoup, Selenium, Requests, lxml, o Scrapy. Una de las librerías más utilizadas es BeautifulSoup pero sólo se puede utilizar en sitios web con contenidos estáticos, para sitios webs con contenidos dinámicos se debe utilizar librerías como Selenium.

¿Qué es VigiAccess?

La VigiBase es una base de datos en donde están contenidos los reportes de caso individual de eventos adversos relacionados a medicamentos provenientes de 110 países miembros de la OMS, esta es mantenida por el Centro de Monitoreo de Uppsala (UMC, Uppsala Monitoring Center). La VigiBase actúa como una base de datos de alcance global en el tema de farmacovigilancia, y se podría considerar como la más grande y exhaustiva del mundo.

La base de datos VigiAccess es una base de datos de resumen de VigiBase, agrupada por principio activo, tipo de evento, año de reporte, grupo etáreo, y región de donde proviene el reporte.

VigiAccess Portada

Instalación de Selenium

El primer paso es la instalación de la librería mediante el comando pip:

!pip install selenium                      # En un Jupyter Notebook
python -m install pip install selenium     # En la línea de comando

El segundo paso es la instalación del driver que es un programa que actúa con una interface con el navegador. Este driver permite la interacción con el sitio web, para este tutorial se utilizó el driver de Google Chrome que se puede encontrar en el sitio web de Chrome Driver

Tras la carga de los paquetes se deben especificar algunas opciones del driver, como el tamaño de ventana. Así mismo se debe especificar la posición relativa (para Jupyter Notebook) en el sistema de chromedriver.

2. Preparación de página con Selenium

Un primer paso es la definición del driver de Chrome, este se crea a partir de la clase base webdriver, el driver se crea mediante el método Chrome y se debe definir la ubicación en el sistema del Driver (DRIVER_PATH). Mediante el método get se puede abrir el sitio web objetivo de este análisis, y se puede verificar su apertura al imprimir el título.

Al ejecutar la celda anterior se abre el driver como un clon de Chrome que permite interactuar con el sitio web mediante instrucciones en código.

ChromeDriver

2.1. Inicio VigiAccess Aceptación de Términos y Condiciones

El acceso a la base se realiza mediante la aceptación de términos y condiciones. En la parte inferior de la página se puede encontrar una casilla de verificación y un botón de acceso. Mediante el método abreviado del teclado Ctrl + Mayus + C se puede hacer una inspección de los elementos de la página, al aplicar el método se abren las herramientas del desarrollador.

Términos y Condiciones

Se puede observar que la casilla de verificación tiene el identificador acceptTermsCheckBox, y el botón es el único elemento con el nombre de clase btn. Estos dos aspectos se pueden utilizar para simular el acceso por parte de un usuario.

<!-- Casilla de verificación -->
<input id="acceptTermsCheckBox" type="checkbox" ng-model="acceptTerms" ng-checked="acceptTerms" class="ng-pristine ng-valid">

<!-- Botón de entrada -->
<button type="button" class="btn btn-primary btn-default btn-sm ng-pristine ng-valid" ng-click="showContent()" ng-model="acceptTerms" ng-disabled="!acceptTerms" disabled="disabled">Search database</button>

A continuación, se utiliza con el driver un selector de id (find_element_by_id) y nombre de clase (find_element_by_class_name) de manera respectiva, tras la selección se aplica el método click.

2.2. Búsqueda de fármaco

Vista Búsqueda de Fármaco

A continuación, se debe buscar el principio activo. En la página se observa un formulario de entrada de caracteres, junto a un botón, si se abre la consola de desarrollo se observa que el formulario cuenta con las siguientes especificaciones:

<input autofocus="" type="search" placeholder="Enter tradename of drug" ng-model="drug" ng-change="noInfo()" class="ng-pristine ng-valid">

Para este caso se puede utilizar un selector de tipo xpath (find_element_by_xpath), en donde se tiene en cuenta el tipo de elemento y además se pueden realizar consultas de las propiedades del elemento, para este formulario se hace selección de un elemento de tipo "input" y la propiedad type con valor "search". Tras seleccionar el formulario se envía el string con el nombre del fármaco al formulario.

En el caso del botón se tiene la siguiente información:

<button class="btn btn-primary btn-default btn-sm" ng-click="getDrug(drug)" ng-disabled="drug.length == 0" disabled="disabled">Search</button>

Se puede realizar la selección de un elemento de tipo "button" con la propiedad ng-click en forma de llamada de función de javascript "getDrug(drug)".

1.3. Apertura de Nodos

Nodos de Consulta

Para este ejemplo se abre el primer nodo de Reacciones Adversas a Fármacos (ADR, Adverse Drug Reactions).

<h4 class="panel-title">
    <a class="accordion-toggle" ng-click="toggleOpen()" accordion-transclude="heading">
        <span class="pull-left glyphicon ng-scope glyphicon-chevron-right" ng-class="{'glyphicon-chevron-down': accordionState.adrDistributionOpen, 'glyphicon-chevron-right': !accordionState.adrDistributionOpen}"></span>
        <span class="ng-scope">Adverse drug reactions (ADRs)</span>
    </a>
</h4>

Como se observa en la figura tenemos varios contenedores para cada sección de interés, todos los contenedores contienen un texto de hipervínculo de tipo "a" que tienen la clase "accordion-toggle". La diferencia entre los contenedores es un elemento de tipo "span" con el contenido de texto de cada sección de interés.

La selección del elemento se puede realizar mediante el método find_element_by_xpath, con la siguiente consulta:

"//a[@class='accordion-toggle' and ./span[contains(text(),'Adverse drug reactions (ADRs)')]]"

A continuación, se deben abrir los nodos para cada clase de reacción adversa:

Nodos Clases ADR


Esto se puede lograr al realizar click en todos los elementos de tipo "span" con clase ng-binding y ng-scope. Se debe dar un tiempo de espera de 1 segundo entre cada item.

A continuación se da click en todos los elementos de tipo "a" y clase ng-scope. Al dar click sobre estos elementos se cargan todos las RAM restantes.

Al realizar todos los procedimientos de manera satisfactoria quedan abiertos todos los nodos y se puede almacenar el contenido del sitio web en este caso en la variable page_source. Se puede cerrar el driver mediante el método quit().

2. Conversión de información de RAM a formato tabular

El primer paso es la conversión del archivo a una estructura de datos para manipulación, primero se toma page_source que tiene todos los pares reacción y frecuencia para cada grupo y elemento.

Los pares de reacción y frecuencia de reportes se pueden extraer de la estructura al tomar todos los elementos de tipo "span" con clase ng-binding.

2.1. Revisión Categorías RAM

Ahora se toma el estado de la página previo a la apertura de los nodos para cada categoría de RAM, contenido en RAM_categories. El archivo en mención contiene sólo la información de las categorías de RAM por sistema fisiológico. A continuación, se extrae el texto de todos los elementos span con clase ng-binding.

Tras las manipulaciones correspondientes, se puede obtener una visión general del perfil de seguridad del fármaco con las reacciones adversas más reportadas a nivel global.

3. Extracción de reacciones por año

Algunos de los pasos previamente mostrados se pueden unir dentro de una función (colocarSitioPrimerNivel) para facilitar las consultas.

A continuación se muestra la inicialización del webdriver, su manipulación, extracción de la información y cierre.

4. Extracción de RAM por sexo

A continuación se muestra el mismo procedimiento pero con extracción de información de sexo reportado.

5. Extracción de distribución de edad

6. Extracción de Continente de Origen RAM

Conclusión

En este tutorial vimos como realizar web scrapping dinámico en un sitio web de reporte globales de reacciones adversas, así mismo se muestra una propuesta para la transformación y visualización de estos datos. Una desventaja de los métodos de web scrapping dinámicos es que son relativamente demorados, ya que el driver tiene que hacer varias interacciones con la páginas, sin embargo es un método muy eficiente si se le compara con una extracción manual de la información.